package com.xebest.util.seq;


import com.xebest.util.DateUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;

/**
 * 财务中心序列号生成规则类
 *
 * @author 李贝贝
 */
@Component
public class FinanceSeqUtil {

    public static FinanceSeqUtil seqUtils = null;

    @Autowired
    protected RedisTemplate<String, String> redisTemplate;

    @PostConstruct
    public void init() {
        seqUtils = this;
    }

    /**
     * 获取或者重新初始化seq
     *
     * @param
     * @return
     * @author: 邓国磊
     * @createTime: 2017/6/15 10:57
     * @history:
     */
    private String getOrSetKeyNextSeq(String seqName, String startNum) {
        ValueOperations<String, String> redis = redisTemplate.opsForValue();
        Long val = null;
        Boolean isOk = redisTemplate.hasKey(seqName);
        if (StringUtils.isNotBlank(startNum)) {
            redis.set(seqName, startNum);
            return startNum;
        } else if (!isOk) {
            if (StringUtils.isBlank(startNum)) {
                startNum = "1";
            }
            redis.set(seqName, startNum);
            return startNum;
        } else {
            val = redis.increment(seqName, 1);
            return val.toString();
        }
    }

    private String getDateStr() {
        Calendar now = Calendar.getInstance();
        //获得6为日期
        String y = String.valueOf(now.get(Calendar.YEAR)).substring(2, 4);
        String m = String.valueOf(now.get(Calendar.MONTH) + 1);
        if (m.length() < 2) {
            m = "0" + m;
        }
        String d = String.valueOf(now.get(Calendar.DAY_OF_MONTH));
        if (d.length() < 2) {
            d = "0" + d;
        }
        return y + m + d;
    }

    /**
     * 根据seqName 查询自增长值 每次增长为1
     *
     * @param seqName  seqName
     * @param startNum 起始值 只有第一次生效
     * @return
     */
    public String getNextSeq(String seqName, String startNum) {

        ValueOperations<String, String> redis = redisTemplate.opsForValue();
        Boolean isOk = redisTemplate.hasKey(seqName);

        if (isOk) {
            Long val = redis.increment(seqName, 1);
            return val.toString();
        } else {
            if (StringUtils.isBlank(startNum)) {
                startNum = "1";
            }
            redis.set(seqName, startNum);
            return startNum;
        }
    }

    private String getLastNum(String seqName) {
        String lastNum;
        String seqNumStr = getOrSetKeyNextSeq(seqName, null);
        int seqNum = Integer.parseInt(seqNumStr);
        //当自增数大于9999重置为1开始
        if (seqNum > 9999) {
            seqNumStr = getOrSetKeyNextSeq(seqName, "1");
        }
        //计算当前自增数量需要补全的前缀字符
        int len = 4 - seqNumStr.length();
        //补全前缀
        StringBuilder prefixStr = new StringBuilder("");
        if (len > 0) {
            for (int i = 0; i < len; i++) {
                prefixStr.append("0");
            }
        }
        //格式化
        lastNum = prefixStr.toString() + seqNumStr;
        return lastNum;
    }

    private int getRandom(int min, int max) {
        Random random = new Random();
        int randNumber = random.nextInt(max - min) + min;
        return randNumber;
    }

    /**
     * 售后单信息  售后单号序列号生成
     * 生成规则：SHD+6位年月日+4位随机数+4位流水号
     *
     * @return String
     * @author: wangyp
     * @createTime: 2017年6月27日 下午15:49:58
     * @history:
     */
    public String createAferSaleCode() {
        StringBuilder purchOrder = new StringBuilder("SHD");
        //6位年月日
        purchOrder.append(this.getDateStr());
        //获得四位随机数
        int randNumber = this.getRandom(1000, 10000);
        purchOrder.append(randNumber);
        //获得4位增长数
        String lastStr = this.getLastNum(XeVenSeqContents.ERP_PURCH_ORDER_PURCHORDER);
        purchOrder.append(lastStr);
        return purchOrder.toString();
    }

    /**
     * 退款单信息  退款单号序列号生成
     * 生成规则：TK+6位年月日+4位随机数+4位流水号
     *
     * @return String
     * @author: wangyp
     * @createTime: 2017年6月27日 下午16:49:58
     * @history:
     */
    public String createRefundCode() {
        StringBuilder refundCode = new StringBuilder("TK");
        //6位年月日
        refundCode.append(this.getDateStr());
        //获得四位随机数
        int randNumber = this.getRandom(1000, 10000);
        refundCode.append(randNumber);
        //获得4位增长数
        String lastStr = this.getLastNum(XeVenSeqContents.ERP_ORDERREFUND_REFUND_CODE);
        refundCode.append(lastStr);
        return refundCode.toString();
    }

    /**
     * 财务收款单信息  收款编号
     * 生成规则：Sk+6位年月日+4位随机数+4位流水号
     *
     * @param :
     * @author: Wangyp
     * @createTime: 2017/8/14 19:07
     * @return:String
     */
    public String createSbillCode() {
        StringBuilder refundCode = new StringBuilder("SK");
        //6位年月日
        refundCode.append(this.getDateStr());
        //获得四位随机数
        int randNumber = this.getRandom(1000, 10000);
        refundCode.append(randNumber);
        //获得4位增长数
        String lastStr = this.getLastNum(XeVenSeqContents.ERP_FINSALESBILL_SBILL_CODE);
        refundCode.append(lastStr);
        return refundCode.toString();
    }

    /**
     * 财务收款单信息  收款编号
     * 生成规则：BC+年月日+下划线+第几批审核。
     *
     * @param :
     * @author: RCZ
     * @createTime: 2017/10/31 14:30
     * @return:String
     */
    public String createCheckCode() {
        StringBuilder refundCode = new StringBuilder("BC");
        //6位年月日
        String randNumber = DateUtil.getDay(new Date());
        refundCode.append(randNumber);
        //获得1位增长数
        String lastStr = this.getLastCheckNum(XeVenSeqContents.ERP_ORDER_CHECKBATCHNUMBER);
        refundCode.append("_" + lastStr);
        return refundCode.toString();
    }

    /**
     * 生成预付单单号
     *
     * @return String
     * @author: 杜春静
     * @createTime: 2017年12月4日 下午5:21:47
     * @history:
     */
    public String createPrepayBill() {
        StringBuilder refundCode = new StringBuilder("SK");
        //6位年月日
        refundCode.append(this.getDateStr());
        //获得四位随机数
        int randNumber = this.getRandom(1000, 10000);
        refundCode.append(randNumber);
        //获得4位增长数
        String lastStr = this.getLastNum(XeVenSeqContents.ERP_FINANCE_PREPAY_BILL_SEQ);
        refundCode.append(lastStr);
        return refundCode.toString();
    }

    private String getLastCheckNum(String seqName) {
        String lastNum;
        String seqNumStr = getOrSetKeyNextSeq(seqName, null);
        int seqNum = Integer.parseInt(seqNumStr);
        //当自增数大于9999重置为1开始
        if (seqNum > 9999) {
            seqNumStr = getOrSetKeyNextSeq(seqName, "1");
        }
        lastNum = seqNumStr;
        return lastNum;
    }
}
